//Memory, by Alejandro Lizaola, DCI

module Memory(Address,clk,arst,wr_data,Memdata,Mem_wr,Mem_rd);
  input clk,arst,Mem_wr,Mem_rd;
  input [31:0]Address;
  input [31:0]wr_data;
  output[31:0]Memdata;
  
  reg [31:0] mem_array[0:63];
  
  always@(posedge clk or posedge arst )
  begin
    if (arst) begin
      //Primer operando
     mem_array[0] <= 32'b000011_11110_00001_0000000000000000;    //carga de registro 1
     mem_array[1] <= 32'b000100_11110_00001_0000000000000010;    //Branch a direccion 4
     mem_array[2] <= 32'b000011_11110_00010_0000000000000000;    //carga en registro 2 primer operando
     mem_array[3] <= 32'b000010_00000000000000000000000101;      //jump a operacion
     mem_array[4] <= 32'b000010_00000000000000000000000001;      //jump a direccion 1
     
     //Operacion a realizar
     mem_array[5] <= 32'b000100_11110_00010_0000000000000011;    //si reg30 == reg2, branch a direccion 9
     mem_array[6] <= 32'b000100_11110_00001_0000000000000011;    //si reg31 == reg1,  branch a direccion 10
     mem_array[7] <= 32'b000011_11110_00011_0000000000000000;    //carga en registro 3 operacion a realizar
     mem_array[8] <= 32'b000010_00000000000000000000001011;         //jump a direccion 11
     mem_array[9] <= 32'b000010_00000000000000000000000101;    //regresamos a direccion 5
     mem_array[10] <= 32'b000010_00000000000000000000000110;    //regresamos a direccion 6
    
     //segundo operando
     mem_array[11] <= 32'b000100_11110_00011_0000000000000011;    //si reg30 == reg3, branch a direccion 15
     mem_array[12] <= 32'b000100_11110_00001_0000000000000011;    //si reg31 == reg1,  branch a direccion 16
     mem_array[13] <= 32'b000011_11110_00100_0000000000000000;    //carga en registro 4 operacion a realizar
     mem_array[14] <= 32'b000010_00000000000000000000010001;         //jump a direccion 17
     mem_array[15] <= 32'b000010_00000000000000000000001011;    //regresamos a direccion 11
     mem_array[16] <= 32'b000010_00000000000000000000001100;    //regresamos a direccion 12
     
     //Proceso de operaciones
     mem_array[17] <= 32'b000100_00011_00101_0000000000000101;    //si reg3 == reg5 (suma), branch a dir23
     mem_array[18] <= 32'b000100_00011_00110_0000000000000010;    //si reg3 == reg6 (res), branch a dir21
     mem_array[19] <= 32'b000011_00000_11111_0000000000010101;    //ERROR
     mem_array[20] <= 32'b000010_00000000000000000000011000;      //Jump a direccion 24
     mem_array[21] <= 32'b000000_00010_00100_11111_00000_100010;  //Substract reg1-reg2 --->reg 17
     mem_array[22] <= 32'b000010_00000000000000000000011000;    //regresamos a direccion 24
     mem_array[23] <= 32'b000000_00010_00100_11111_00000_100000;  //Add, reg1+reg2 ---> reg 16 
     
    //Regreso a instruccion 1
     mem_array[24] <= 32'b000100_11110_00100_0000000000000001;    //si reg4 == reg10, branch a direccion 26
     mem_array[25] <= 32'b000010_00000000000000000000000001;      //si no se cumple la igualdad regresamos a dir1
     mem_array[26] <= 32'b000010_00000000000000000000011000;      //si se cumple la igualdad regresamos a dir24
      
    end
  else if(Mem_wr)
    mem_array[Address] <= wr_data;
  end
  
  assign Memdata = (Mem_rd) ?mem_array[Address] : 0;
endmodule
      
  